﻿using System;
using System.Collections.Generic;
//new
using System.Xml;
using JRCore.protocol;
using Apache.NMS;
using Apache.NMS.ActiveMQ;
//using DataInterfaceDLL;


namespace MCTXCLMQ
{
    public class MQ
    {
        private string m_uri;
        private string m_SendTopic;
        private IConnectionFactory m_factory;
        private IConnection m_connection;
        private ISession m_session;
        private IMessageProducer m_producer;

        public delegate void Log(string txt);
        public delegate void MessageInComing(string txt);
        //public event Log LogEvent;
        public bool link;//连接状态
        
        public MQ()
        {
            m_producer = null;
            m_factory = null;
            m_connection = null;
            m_session = null;
        }

        public MQ(string mquri, string mqSendTopic)
        {
            m_uri = mquri;
            m_SendTopic = mqSendTopic;
            link = false;
        }

        ~MQ()
        {
            Stop();
        }

        public void Start()
        {
            try
            {
                m_factory = new ConnectionFactory(m_uri);
                m_connection = m_factory.CreateConnection();
                if (m_connection != null)
                {
                    m_connection.ConnectionInterruptedListener += new ConnectionInterruptedListener(connection_ConnectionInterruptedListener);
                    m_connection.ConnectionResumedListener += new ConnectionResumedListener(connection_ConnectionResumedListener);
                    m_connection.ExceptionListener += new ExceptionListener(connection_ExceptionListener);
                    m_connection.Start();
                    Resume();
                }
            }
            catch (Exception er)
            {
                //if (LogEvent != null) { LogEvent("MQ Start()异常" + er.Message); }
                LogHelper.WriteLog(typeof(MQ),er,er.Message);
            }
        }

        public void Resume()
        {
            try
            {
                m_session = m_connection.CreateSession();
                if (m_session != null)
                {
                    m_producer = m_session.CreateProducer(new Apache.NMS.ActiveMQ.Commands.ActiveMQTopic(m_SendTopic));
                    if ((m_producer != null) && (m_connection.IsStarted))
                    {
                        link = true;
                        //if (LogEvent != null) { LogEvent("MQ启动"); }
                        LogHelper.WriteLog(typeof(MQ), "MQ启动" + " ++++++ m_SendTopic ++++++ ");

                    }
                }
            }
            catch (Exception er)
            {
                //if (LogEvent != null) { LogEvent("MQ Resume()异常" + er.Message); }
                LogHelper.WriteLog(typeof(MQ), er, "MQ Resume()异常" + " ++++++ m_SendTopic ++++++ " + er.Message);

            }
        }

        public void Stop()
        {
            try
            {
                if (m_producer != null)
                {
                    m_producer.Close();
                    m_producer.Dispose();
                    m_producer = null;
                }
            }
            catch { }

            try
            {
                if (m_session != null)
                {
                    m_session.Close();
                    m_session.Dispose();
                    m_session = null;
                }
            }
            catch { }

            link = false;

            LogHelper.WriteLog(typeof(MQ), "MQ停止" + " ++++++ m_SendTopic ++++++ ");

        }

        public void Close()
        {
            Stop();
            try
            {
                if (m_connection != null)
                {
                    m_connection.ConnectionResumedListener -= connection_ConnectionResumedListener;
                    m_connection.ExceptionListener -= connection_ExceptionListener;
                    m_connection.ConnectionInterruptedListener -= connection_ConnectionInterruptedListener;
                    m_connection.Stop();
                    m_connection.Close();
                    m_connection.Dispose();
                    m_connection = null;
                }
            }
            catch
            { }

            LogHelper.WriteLog(typeof(MQ), "MQ退出" + " ++++++ m_SendTopic ++++++ ");

        }

        void connection_ExceptionListener(Exception exception)
        {
            //if (LogEvent != null) { LogEvent("connection_ExceptionListener()异常" + exception.Message); }
            LogHelper.WriteLog(typeof(MQ), exception, "connection_ExceptionListener()异常" + exception.Message);

        }

        void connection_ConnectionResumedListener()
        {
            //if (LogEvent != null) { LogEvent("MQ重连"); }
            LogHelper.WriteLog(typeof(MQ), "MQ重连" + " ++++++ m_SendTopic ++++++ ");

            Resume();
        }

        void connection_ConnectionInterruptedListener()
        {
            //if (LogEvent != null) { LogEvent("MQ断开"); }
            LogHelper.WriteLog(typeof(MQ), "MQ断开" + " ++++++ m_SendTopic ++++++ ");
            Stop();
        }

        public bool SendMQMessage(string strText,string key,string value)
        {
            bool ans = false;
            try
            {
                if (m_producer != null)
                {
                    ITextMessage msg = m_producer.CreateTextMessage();
                    msg.Text = strText;
                    msg.Properties.Clear();
                    msg.Properties.SetString(key, value);
                    if((m_connection!=null)&&(m_connection.IsStarted))
                    {
                        m_producer.Send(msg, Apache.NMS.MsgDeliveryMode.NonPersistent, Apache.NMS.MsgPriority.Normal, TimeSpan.MinValue);
                        ans = true;
                    } 
                }
                else
                {
                    Start();
                }
            }
            catch (Exception er)
            {
                ans = false;
                //if (LogEvent != null) { LogEvent("SendMQMessage()异常" + er.Message); }
                LogHelper.WriteLog(typeof(MQ), er, "SendMQMessage()异常" + er.Message);
                if (er.Message.Contains("The connection is already closed"))
                {
                    link = false;
                    Stop();
                    Start();
                }
                //if (er.Message.Contains("The connection is already closed"))
                //{
                //    link = false;
                //    Resume();
                //}
            }
            return ans;
        }

        public DIY.MQParam MakeMqParam(DataRecvRecord record)
        {
            DIY.MQParam param = null;
            try
            {
                if (record != null)
                {
                    param = new DIY.MQParam();
                    param.CARTYPE = record.P21;
                    param.CARNUM = record.P23;
                    param.PASSDATE = record.P19;
                    param.ADDRESSCODE = record.P11;
                    param.DEPARTMENTCODE = record.P12;
                    param.DATASOURCE = record.P7;
                    param.DEVICECODE = record.P8;
                    param.LANENUM = record.P17;
                    param.CARSPEED = record.P27;
                    param.PIC1 = record.P37;
                    param.PIC2 = record.P41;
                    switch (record.P16)
                    {
                        case "2": param.DIRID = "3";
                            break;
                        case "3": param.DIRID = "2";
                            break;
                        default: param.DIRID = record.P16;
                            break;

                    }
                    param.TYPECOLOR = record.P22;
                }
            }
            catch (Exception er)
            {
                param = null;
                //if (LogEvent != null) { LogEvent("MakeMqParam()异常" + er.Message); }
                LogHelper.WriteLog(typeof(MQ), er, "MakeMqParam()异常" + " ++++++ m_SendTopic ++++++ " + er.Message);

            }
            return param;
        }


        public string MakeXml(DIY.MQParam mqparam)
        {
            string ans = "";
            XmlDocument doc = new XmlDocument();
            Dictionary<string, string> kvp = new Dictionary<string, string>();
            XmlElement root;
            try
            {
                root = doc.CreateElement("JARI");
                doc.AppendChild(root);
                CreateNode(doc, "JARI", "TGS", "", null);
                CreateNode(doc, "TGS", "CARINFO", "", null);
                CreateNode(doc, "CARINFO", "CARTYPE", mqparam.CARTYPE, null);
                CreateNode(doc, "CARINFO", "CARNUM", mqparam.CARNUM, null);
                CreateNode(doc, "CARINFO", "PASSDATE", mqparam.PASSDATE, null);
                CreateNode(doc, "CARINFO", "ADDRESSCODE", mqparam.ADDRESSCODE, null);
                CreateNode(doc, "CARINFO", "DEPARTMENTCODE", mqparam.DEPARTMENTCODE, null);
                CreateNode(doc, "CARINFO", "DATASOURCE", mqparam.DATASOURCE, null);
                CreateNode(doc, "CARINFO", "DEVICECODE", mqparam.DEVICECODE, null);
                CreateNode(doc, "CARINFO", "LANENUM", mqparam.LANENUM, null);
                CreateNode(doc, "CARINFO", "CARSPEED", mqparam.CARSPEED, null);
                CreateNode(doc, "CARINFO", "PIC1", mqparam.PIC1, null);
                CreateNode(doc, "CARINFO", "PIC2", mqparam.PIC2, null);
                CreateNode(doc, "CARINFO", "DIRID", mqparam.DIRID, null);
                CreateNode(doc, "CARINFO", "TYPECOLOR", mqparam.TYPECOLOR, null);
                ans = doc.OuterXml;
                doc.RemoveAll();
            }
            catch (Exception er)
            {
                //if (LogEvent != null) { LogEvent("MakeXml()异常" + er.Message); }
                LogHelper.WriteLog(typeof(MQ), er, "MakeXml()异常" + " ++++++ m_SendTopic ++++++ " + er.Message);

            }
            return ans;
        }

        

        private void CreateNode(XmlDocument xmldoc, string parentnodename, string nodename, string innertext, Dictionary<string, string> attributes)
        {
            if ((xmldoc != null) && (parentnodename != null) && (parentnodename != "") && (nodename != null) && (nodename != ""))
            {
                XmlNode parentnode = xmldoc.SelectSingleNode("descendant::" + parentnodename);
                if (parentnode != null)
                {
                    XmlElement xe = xmldoc.CreateElement(nodename);
                    if (innertext != null)
                    {
                        xe.InnerText = innertext;
                    }
                    if (attributes != null)
                    {
                        foreach (KeyValuePair<string, string> pair in attributes)
                        {
                            xe.SetAttribute(pair.Key, pair.Value);
                        }
                    }
                    parentnode.AppendChild(xe);
                }
            }
        }

    }
}
